/*
 * 
 * 
 * @author: Oren Zamir
 */
package org.valire.usermanagement.services;

import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.valire.usermanagement.beans.Role;
import org.valire.usermanagement.beans.User;
import org.valire.util.lang.Args;



/**
 * The Class RolesServiceImpl.
 */
public class RolesServiceImpl implements RolesService {

	/** The Constant logger. */
	//private final static Log logger = LogFactory.getLog(RolesServiceImpl.class);

	/** The roles dao. */
	@Resource
	private RoleDao roleDao;
	
	/**
	 * Sets the user dao.
	 *
	 * @param roleDao the new user dao
	 */
	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}
	

	/* (non-Javadoc)
	 * @see org.valire.usermanagement.services.RolesService#createRole(org.valire.usermanagement.beans.Role)
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	@PreAuthorize("hasPermission(#role, 'org.valire.usermanagement.services.RolesService.createRole(role)')")
	public Role createRole(Role newRole) {
		Args.assertNotNull(newRole);
		Iterator<Role> rolesIt = this.roleDao.getAllAvailableRoles().iterator();
		while (rolesIt.hasNext()) {
			Role role = (Role) rolesIt.next();
			if(role.equals(newRole)){
				throw new IllegalArgumentException("Role '"+role.getRoleName()+"' already exists");
			}
			
		}
		this.roleDao.create(newRole);
		return newRole;
	}
	
	
	/* (non-Javadoc)
	 * @see org.valire.usermanagement.services.RolesService#removeRole(org.valire.usermanagement.beans.Role)
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	@PreAuthorize("hasPermission(#role, 'org.valire.usermanagement.services.RolesService.removeRole(role)')")
	public void removeRole(Role role) {
		Args.assertNotNull(role);
		this.roleDao.setPersistentClass(Role.class);
		this.roleDao.delete(role.getId());
	}

	/* (non-Javadoc)
	 * @see org.valire.usermanagement.services.RolesService#updateRole(org.valire.usermanagement.beans.Role)
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	@PreAuthorize("hasPermission(#role, 'org.valire.usermanagement.services.RolesService.updateRole(role)')")
	public void updateRole(Role role) {
		Args.assertNotNull(role.getId());
		Args.assertNotNull(role.getRoleName());
		Iterator<Role> rolesIt = this.roleDao.getAllAvailableRoles().iterator();
		while (rolesIt.hasNext()) {
			Role tmpRole = (Role) rolesIt.next();
			if(tmpRole.equals(role)){
				throw new IllegalArgumentException("Role '"+role.getRoleName()+"' already exists");
			}
			
		}
		
		roleDao.merge(role);		
	}
	
	/* (non-Javadoc)
	 * @see org.valire.usermanagement.services.RolesService#getAllRoles()
	 */
	@Override
//	@PreAuthorize("hasPermission(null, 'org.valire.usermanagement.services.RolesService.getAllRoles()')")	
	public List<Role> getAllRoles() {
		return this.roleDao.getAllAvailableRoles();
	}

	/* (non-Javadoc)
	 * @see org.valire.usermanagement.services.RolesService#getMethodRoles(java.lang.String)
	 */
	@Override
	@PreAuthorize("hasPermission(#role, 'org.valire.usermanagement.services.RolesService.getMethodRoles(method)')")	
	public List<Role> getMethodRoles(String method) {
		Args.assertNotNull(method);
		return this.roleDao.getAllRolesForMethod(method);
	}

	/* (non-Javadoc)
	 * @see org.valire.usermanagement.services.RolesService#checkMethodAccessForRole(org.valire.usermanagement.beans.User, java.lang.String)
	 */
	@Override
//	@PreAuthorize("hasPermission(#role, 'org.valire.usermanagement.services.RolesService.checkMethodAccessForRole(user,method)')")	
	public boolean checkMethodAccessForRole(User user, String method) {
		Args.assertNotNull(user);
		Args.assertNotNull(method);
		return this.roleDao.canUserAccessMethod(user,method);
	}

	@Override
	public Role getRole(String roleName){
		List<Role> allRoles = getAllRoles();
		for (Role role : allRoles) {
			if(role.getRoleName().equals(roleName))
				return role;
		}
		return null;
	}
}
